<script lang="ts" setup>
import type { NotificationItem, TabItem } from '@vben/layouts';

import { computed, onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';

import { AuthenticationLoginExpiredModal } from '@vben/common-ui';
import { LOGIN_PATH, PROFILE_PATH } from '@vben/constants';
import { useTabs, useWatermark } from '@vben/hooks';
import { ApartmentOutlined, SwapOutlined, UserOutlined } from '@vben/icons';
import {
  BasicLayout,
  LockScreen,
  Notification,
  UserDropdown,
} from '@vben/layouts';
import { preferences } from '@vben/preferences';
import { useAccessStore, useUserStore } from '@vben/stores';

import { asyncComputed } from '@vueuse/core';
import { Badge } from 'ant-design-vue';

import { asyncFindUrlById, unPlayUser } from '#/api';
import { ExtendNoticeApi } from '#/api/basic/msg/extendNotice';
import { NoticeRemindModeEnum } from '#/enums/base';
import { useMessage } from '#/hooks/web/useMessage';
import { $t } from '#/locales';
import { useAuthStore } from '#/store';
import LoginForm from '#/views/_core/authentication/login.vue';
import MsgWrapper from '#/views/basic/msg/extendNotice/Wrapper.vue';

import SwitchTenant from './components/switch-tenant.vue';

const userStore = useUserStore();
const authStore = useAuthStore();
const accessStore = useAccessStore();
const { createMessage } = useMessage();
const { destroyWatermark, updateWatermark } = useWatermark();

const switchTenantRef = ref();
const msgWrapperRef = ref();
const notifications = ref<TabItem[]>([]);
const noticeIdsRef = ref<string[]>([]);

const { push, currentRoute } = useRouter();

const menus = computed(() => [
  {
    handler: () => {
      push({ path: PROFILE_PATH });
    },
    icon: UserOutlined,
    text: $t('common.profile.index'),
  },
  {
    handler: () => {
      switchTenantRef.value.setData({
        isUpdate: false,
      });
      switchTenantRef.value.open();
    },
    icon: SwapOutlined,
    text: $t('common.profile.switch'),
  },
  {
    handler: () => {
      push({
        name: '注册企业',
      });
    },
    icon: ApartmentOutlined,
    text: $t('common.profile.tenant'),
  },
  {
    separator: true,
  },
]);

const avatar = asyncComputed(async () => {
  const url = userStore.userInfo?.avatarId ?? preferences.app.defaultAvatar;
  let realSrc = '';
  if (url && url.startsWith('http')) {
    realSrc = url;
  } else if (url && url.startsWith('data:')) {
    realSrc = url;
  } else {
    realSrc = await loadSrc(url);
  }
  return realSrc;
});

async function loadMyMsg() {
  const allMsg = await ExtendNoticeApi.myNotice({
    current: 1,
    size: 5,
    model: {},
  });

  const todoList = [];
  const earlyWarningList = [];
  const noticeList = [];
  const todoPages = allMsg?.todoList?.records;
  if (todoPages) {
    for (const item of todoPages) {
      const row = {
        date: item.createdTime,
        isRead: item.isRead,
        title: item.title,
        id: item.id,
        autoRead: item.autoRead,
      };
      noticeIdsRef.value.push(item.id as string);
      todoList.push(row);
    }
  }

  const earlyWarningPages = allMsg?.earlyWarningList?.records;
  if (earlyWarningPages) {
    for (const item of earlyWarningPages) {
      const row = {
        date: item.createdTime,
        isRead: item.isRead,
        title: item.title,
        id: item.id,
        autoRead: item.autoRead,
      };
      noticeIdsRef.value.push(item.id as string);
      earlyWarningList.push(row);
    }
  }
  const noticePages = allMsg?.noticeList?.records;
  if (noticePages) {
    for (const item of noticePages) {
      const row = {
        date: item.createdTime,
        isRead: item.isRead,
        title: item.title,
        id: item.id,
        autoRead: item.autoRead,
      };
      noticeIdsRef.value.push(item.id as string);
      noticeList.push(row);
    }
  }

  notifications.value = [];

  notifications.value.push(
    {
      key: NoticeRemindModeEnum.TO_DO,
      name: '待办',
      total: allMsg?.todoList?.total ?? 0,
      data: todoList,
    },
    {
      key: NoticeRemindModeEnum.EARLY_WARNING,
      name: '预警',
      total: allMsg?.earlyWarningList?.total ?? 0,
      data: earlyWarningList,
    },
    {
      key: NoticeRemindModeEnum.NOTICE,
      name: '提醒',
      total: allMsg?.noticeList?.total ?? 0,
      data: noticeList,
    },
  );
}

const count = computed(() => {
  let num = 0;
  for (let i = 0; i < notifications.value.length; i++) {
    num += Number(notifications.value[i]?.total ?? 0);
  }
  return num;
});

onMounted(() => {
  loadMyMsg();
});

setInterval(() => {
  const { path } = currentRoute.value;
  if (path !== LOGIN_PATH) {
    loadMyMsg();
  }
}, 5 * 60_000);

async function loadSrc(fileId: string) {
  if (!fileId) {
    return preferences.app.defaultAvatar;
  }
  const api = asyncFindUrlById;
  const res = await api(fileId);

  return res.code === 0 ? (res.data as string) : preferences.app.defaultAvatar;
}

async function handleLogout() {
  await authStore.logout(false);
}

function handleLogoutPlay() {
  unPlayUser({}).then((data) => {
    accessStore.setAccessToken(data.token);
    accessStore.setRefreshToken(data.refreshToken);
    createMessage.success('退出扮演成功！');
    const { closeCurrentTab } = useTabs();
    closeCurrentTab();
    setTimeout(() => {
      location.reload();
    }, 600);
  });
}

function handleNoticeClear() {}

async function handleMakeAll() {
  if (noticeIdsRef.value && noticeIdsRef.value.length > 0) {
    const flag = await ExtendNoticeApi.mark(noticeIdsRef.value);
    if (flag) {
      loadMyMsg();
    }
  }
}

function handleViewAll() {
  push({
    // name: RouteEnum.BASIC_MY_MSG,
    path: '/msg/myMsg',
  });
}

async function handleRead(record: NotificationItem) {
  if (record.autoRead) {
    const flag = await ExtendNoticeApi.mark([record.id as string]);
    if (flag) {
      loadMyMsg();
    }
  }
  msgWrapperRef.value.setData({ id: record.id });
  msgWrapperRef.value.open();
}

watch(
  () => ({
    enable: preferences.app.watermark,
    content: preferences.app.watermarkContent,
  }),
  async ({ enable, content }) => {
    if (enable) {
      await updateWatermark({
        content:
          content ||
          `${userStore.userInfo?.username} - ${userStore.userInfo?.nickName}`,
      });
    } else {
      destroyWatermark();
    }
  },
  {
    immediate: true,
  },
);
</script>

<template>
  <BasicLayout @clear-preferences-and-logout="handleLogout">
    <template #user-dropdown>
      <UserDropdown
        :avatar
        :menus
        :text="userStore.userInfo?.nickName"
        :description="userStore.userInfo?.username"
        @logout="handleLogout"
        @logout-play="handleLogoutPlay"
      />
      <SwitchTenant ref="switchTenantRef" />
    </template>
    <template #notification>
      <Badge :count="count" dot>
        <Notification
          :notification-tab-list="notifications"
          @clear="handleNoticeClear"
          @read="handleRead"
          @make-all="handleMakeAll"
          @view-all="handleViewAll"
        />
        <MsgWrapper ref="msgWrapperRef" />
      </Badge>
    </template>
    <template #extra>
      <AuthenticationLoginExpiredModal
        v-model:open="accessStore.loginExpired"
        :avatar
      >
        <LoginForm />
      </AuthenticationLoginExpiredModal>
    </template>
    <template #lock-screen>
      <LockScreen :avatar @to-login="handleLogout" />
    </template>
  </BasicLayout>
</template>
